package graphicalUserInterface;

import java.io.IOException;
import java.util.ArrayList;

import javax.xml.bind.JAXBException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;

import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.xml.sax.SAXException;

import email.EmailManager;
import entity.Category;
import entity.Source;
import exception.NullVariableFound;

import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;

import settings.MasterController;

//@author U096819H
public class SettingsScreen extends Dialog {

	protected Object result;
	protected Shell shell;
	private Text txtCategory;
	private Text txtAddNewCategory;
	private Text txtSource;
	private Text txtAddNewSource;
	private Combo category_combo;
	private Combo source_combo;
	private Category _cat;
	private Source _src;
	private Composite settingsComposite;
	private Text txtEmail;
	private Text txtPassword;
	private Button btnGo;
	private Text text;

	// @author U096819H
	public SettingsScreen(Shell parent, int style) {
		super(parent, style);
		setText("SWT Dialog");
	}

	// @author U096819H
	public Object open(MasterController mc) {
		createContents(mc);
		shell.open();
		shell.layout();
		Display display = getParent().getDisplay();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
		return result;
	}

	// @author U096819H
	private void createContents(final MasterController mc) {

		// shell box
		shell = new Shell(getParent(), getStyle());
		shell.setSize(450, 328);
		shell.setText(getText());
		shell.setLayout(new FormLayout());

		// COMPOSITE:: Settings
		settingsComposite = new Composite(shell, SWT.NONE);
		FormData fd_composite = new FormData();
		fd_composite.bottom = new FormAttachment(0, 290);
		fd_composite.right = new FormAttachment(0, 434);
		fd_composite.top = new FormAttachment(0, 10);
		fd_composite.left = new FormAttachment(0, 10);
		settingsComposite.setLayoutData(fd_composite);
		settingsComposite.setLayout(new GridLayout(10, false));

		setCategoryBox(mc);

		Label label = new Label(settingsComposite, SWT.SEPARATOR
				| SWT.HORIZONTAL);
		label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false,
				10, 1));

		setSourceBox(mc);

		Label label_1 = new Label(settingsComposite, SWT.SEPARATOR
				| SWT.HORIZONTAL);
		label_1.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false,
				10, 1));

		Label lblEmail = new Label(settingsComposite, SWT.NONE);
		lblEmail.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false,
				false, 1, 1));
		lblEmail.setText("Email");

		final Button btnActivate = new Button(settingsComposite, SWT.CHECK);
		btnActivate.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				if (btnActivate.getSelection()) {
					txtEmail.setEnabled(true);
					txtPassword.setEnabled(true);
					btnGo.setEnabled(true);
				} else {
					txtEmail.setEnabled(false);
					txtPassword.setEnabled(false);
					btnGo.setEnabled(false);
					EmailManager em;
					try {
						em = new EmailManager();
						em.deactivate();
					} catch (Exception e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
			}
		});
		btnActivate.setText("Activate");
		new Label(settingsComposite, SWT.NONE);
		new Label(settingsComposite, SWT.NONE);

		txtEmail = new Text(settingsComposite, SWT.BORDER);
		txtEmail.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				txtEmail.setText("");
			}
		});
		txtEmail.setEnabled(false);
		txtEmail.setText("Email");
		txtEmail.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false,
				4, 1));
		new Label(settingsComposite, SWT.NONE);
		new Label(settingsComposite, SWT.NONE);
		new Label(settingsComposite, SWT.NONE);
		new Label(settingsComposite, SWT.NONE);
		new Label(settingsComposite, SWT.NONE);
		new Label(settingsComposite, SWT.NONE);

		txtPassword = new Text(settingsComposite, SWT.BORDER | SWT.PASSWORD);
		txtPassword.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				txtPassword.setText("");
			}
		});
		txtPassword.setText("Password");
		txtPassword.setEnabled(false);
		txtPassword.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
				false, 4, 1));

		btnGo = new Button(settingsComposite, SWT.NONE);
		btnGo.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				try {
					EmailManager em = new EmailManager();
					em.activate(txtEmail.getText(), txtPassword.getText());
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}

			}
		});
		btnGo.setText("Go");
		btnGo.setEnabled(false);
		new Label(settingsComposite, SWT.NONE);

		Label label_2 = new Label(settingsComposite, SWT.SEPARATOR
				| SWT.HORIZONTAL);
		label_2.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false,
				10, 1));

		Label lblSavingPot = new Label(settingsComposite, SWT.NONE);
		lblSavingPot.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false,
				false, 1, 1));
		lblSavingPot.setText("Saving Pot");

		Label lblToSaveAmt = new Label(settingsComposite, SWT.NONE);
		lblToSaveAmt.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false,
				false, 1, 1));
		lblToSaveAmt.setText(String.valueOf(mc.GetSavingPotAmount()));
		new Label(settingsComposite, SWT.NONE);

		Label lblToSaveAmount = new Label(settingsComposite, SWT.NONE);
		lblToSaveAmount.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false,
				false, 4, 1));
		lblToSaveAmount.setText("To Save");

		text = new Text(settingsComposite, SWT.BORDER);
		text.setText(String.valueOf(mc.GetToSaveAmount()));
		text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));

		Button button = new Button(settingsComposite, SWT.NONE);
		button.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				mc.AdjustToSaveAmount(Double.parseDouble(text.getText()));
			}
		});
		button.setText("Edit");
		new Label(settingsComposite, SWT.NONE);
	}

	// @author U096819H
	public void setSourceBox(final MasterController mc) {
		Label lblSource = new Label(settingsComposite, SWT.NONE);
		lblSource.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false,
				false, 1, 1));
		lblSource.setText("Source");

		source_combo = new Combo(settingsComposite, SWT.READ_ONLY);
		source_combo.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				txtSource.setText(source_combo.getText());
				try {
					_src = mc.GetSourceByName(source_combo.getText());
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
		source_combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
				false, 2, 1));
		refreshSourceList(mc);
		new Label(settingsComposite, SWT.NONE);

		txtSource = new Text(settingsComposite, SWT.BORDER);
		txtSource.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false,
				4, 1));
		txtSource.setText(source_combo.getText());

		// Edit Source
		Button btnEdit = new Button(settingsComposite, SWT.NONE);
		btnEdit.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				ConfirmPrompt cnp = new ConfirmPrompt(settingsComposite
						.getShell(), 65);
				if (cnp.open("Are you sure you want to update?")) {
					try {
						mc.UpdateSource(_src.getId(), txtSource.getText());
						refreshSourceList(mc);
						txtSource.setText(source_combo.getText());
						// Add OK Dialog:: message:: Source Updated.
						NotifyPrompt ntp = new NotifyPrompt(settingsComposite
								.getShell(), 65);
						ntp.open("Source Updated.");
					} catch (Exception e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
			}
		});
		btnEdit.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false,
				1, 1));
		btnEdit.setText("Edit");

		// Remove Source
		Button btnDel = new Button(settingsComposite, SWT.NONE);
		btnDel.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				// Add YES/NO Dialog:: message:: Do you want to delete the ""
				// Source
				ConfirmPrompt cnp = new ConfirmPrompt(settingsComposite
						.getShell(), 65);
				if (cnp.open("Are you sure you want to delete?")) {
					try {
						mc.RemoveSource(_src.getId());
						refreshSourceList(mc);
						txtSource.setText(source_combo.getText());
						// Add OK Dialog:: message:: Source Deleted.
						NotifyPrompt ntp = new NotifyPrompt(settingsComposite
								.getShell(), 65);
						ntp.open("Source Deleted.");
					} catch (Exception e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
			}
		});
		btnDel.setText("Del");
		new Label(settingsComposite, SWT.NONE);
		new Label(settingsComposite, SWT.NONE);
		new Label(settingsComposite, SWT.NONE);
		new Label(settingsComposite, SWT.NONE);

		// Add New Source
		txtAddNewSource = new Text(settingsComposite, SWT.BORDER);
		txtAddNewSource.addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent e) {
				txtAddNewSource.setText("");
			}
		});
		txtAddNewSource.setText("Add New Source");
		txtAddNewSource.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
				false, 4, 1));

		Button btnAdd = new Button(settingsComposite, SWT.NONE);
		btnAdd.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				if (!txtAddNewSource.getText().equalsIgnoreCase(
						"Add New Source")) {
					try {
						mc.AddSource(txtAddNewSource.getText());
						// Add OK Dialog:: message:: New Source Added.
						NotifyPrompt ntp = new NotifyPrompt(settingsComposite
								.getShell(), 65);
						ntp.open("New Source Added.");

						refreshSourceList(mc);
						txtAddNewSource.setText("Add New Source");
						txtSource.setText(source_combo.getText());
					} catch (Exception e1) {
						NotifyPrompt ntp = new NotifyPrompt(settingsComposite
								.getShell(), 65);
						ntp.open("Unable to create new source.");
						e1.printStackTrace();
					}
				}
			}
		});
		btnAdd.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false,
				1, 1));
		btnAdd.setText("Add");
		new Label(settingsComposite, SWT.NONE);

	}

	// @author U096819H
	public void setCategoryBox(final MasterController mc) {
		Label lblCategory = new Label(settingsComposite, SWT.NONE);
		lblCategory.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false,
				false, 1, 1));
		lblCategory.setText("Category");

		category_combo = new Combo(settingsComposite, SWT.READ_ONLY);
		category_combo.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				txtCategory.setText(category_combo.getText());
				try {
					_cat = mc.GetCategoryByName(category_combo.getText());
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		});
		category_combo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
				false, 2, 1));
		refreshCategoryList(mc);
		new Label(settingsComposite, SWT.NONE);

		txtCategory = new Text(settingsComposite, SWT.BORDER);
		txtCategory.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true,
				false, 4, 1));
		txtCategory.setText(category_combo.getText());

		// Edit Category
		Button editButton = new Button(settingsComposite, SWT.NONE);
		editButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				ConfirmPrompt cnp = new ConfirmPrompt(settingsComposite
						.getShell(), 65);
				if (cnp.open("Are you sure you want to update?")) {

					try {
						mc.UpdateCategory(_cat.getId(), txtCategory.getText());
						refreshCategoryList(mc);
						txtCategory.setText(category_combo.getText());
						// Add OK Dialog:: message:: Category Updated.
						NotifyPrompt ntp = new NotifyPrompt(settingsComposite
								.getShell(), 65);
						ntp.open("Category Updated.");
					} catch (Exception e1) {
						NotifyPrompt ntp = new NotifyPrompt(
								settingsComposite.getShell(), 65);
						ntp.open("Unable to update category");
						e1.printStackTrace();
					}
				}
			}
		});
		editButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false,
				false, 1, 1));
		editButton.setText("Edit");

		// Remove Category
		Button removeButton = new Button(settingsComposite, SWT.NONE);
		removeButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				// Add YES/NO Dialog:: message:: Do you want to delete the ""
				// category
				ConfirmPrompt cnp = new ConfirmPrompt(settingsComposite
						.getShell(), 65);
				if (cnp.open("Are you sure you want to delete?")) {
					try {
						mc.RemoveCategory(_cat.getId());
							refreshCategoryList(mc);
							txtCategory.setText(category_combo.getText());
							// Add OK Dialog:: message:: Category Deleted.
							NotifyPrompt ntp = new NotifyPrompt(
									settingsComposite.getShell(), 65);
							ntp.open("Category Deleted.");
						// Add OK Dialog:: message:: Category Deleted.

					} catch (Exception e1) {
						NotifyPrompt ntp = new NotifyPrompt(
								settingsComposite.getShell(), 65);
						ntp.open("Unable to delete category");
						e1.printStackTrace();
					}
				}
			}
		});
		removeButton.setText("Del");
		new Label(settingsComposite, SWT.NONE);
		new Label(settingsComposite, SWT.NONE);
		new Label(settingsComposite, SWT.NONE);
		new Label(settingsComposite, SWT.NONE);

		// Add Category
		txtAddNewCategory = new Text(settingsComposite, SWT.BORDER);
		txtAddNewCategory.addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent e) {
				txtAddNewCategory.setText("");
			}
		});
		txtAddNewCategory.setText("Add New Category");
		txtAddNewCategory.setLayoutData(new GridData(SWT.FILL, SWT.CENTER,
				true, false, 4, 1));

		Button addButton = new Button(settingsComposite, SWT.NONE);
		addButton.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseUp(MouseEvent e) {
				if (!txtAddNewCategory.getText().equalsIgnoreCase(
						"Add New Category")) {
					try {
						mc.AddCategory(txtAddNewCategory.getText());
							NotifyPrompt ntp = new NotifyPrompt(
									settingsComposite.getShell(), 65);
							ntp.open("New Category Added.");
						refreshCategoryList(mc);
						txtAddNewCategory.setText("Add New Category");
						txtCategory.setText(category_combo.getText());

					} catch (Exception e1) {
						NotifyPrompt ntp = new NotifyPrompt(
								settingsComposite.getShell(), 65);
						ntp.open("Unable to add new category");
						e1.printStackTrace();
					}
				}
			}
		});
		addButton.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false,
				false, 1, 1));
		addButton.setText("Add");
		new Label(settingsComposite, SWT.NONE);
	}

	// @author U096819H
	public void refreshCategoryList(final MasterController mc) {
		try {
			ArrayList<Category> catList = mc.GetAllCategory();
			String[] catNames = new String[catList.size()];
			for (int i = 0; i < catList.size(); i++) {
				catNames[i] = catList.get(i).getName();
			}
			category_combo.setItems(catNames);
			category_combo.select(0);			
			try {
				_cat = mc.GetCategoryByName(category_combo.getText());
			} catch (NullVariableFound e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (InstantiationException | IllegalAccessException
				| JAXBException | ParserConfigurationException | SAXException
				| IOException | TransformerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	// @author U096819H
	public void refreshSourceList(final MasterController mc) {
		try {
			ArrayList<Source> srcList = mc.GetAllSource();
			String[] srcNames = new String[srcList.size()];
			for (int i = 0; i < srcList.size(); i++) {
				srcNames[i] = srcList.get(i).getName();
			}
			source_combo.setItems(srcNames);
			source_combo.select(0);
			try {
				_src = mc.GetSourceByName(source_combo.getText());
			} catch (NullVariableFound e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		} catch (InstantiationException | IllegalAccessException
				| JAXBException | ParserConfigurationException | SAXException
				| IOException | TransformerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
